package com.egintra.ovideo.util;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * @className: FailUtil
 * @package: com.egintra.ovideo.util
 * @author XuChao
 * @description: 文件工具类
 * @date: 2023/7/28 14:45
 */
@Slf4j
public class FileUtil implements Serializable {

    /**
     * 给出路径和文件名，将传入Map通过键值对写入传入的文件中
     * @param directoryPath  路径 比如D:\\a\\b\\  主要最后面也需要\\
     * @param fileName  需要创建的文件名
     * @param dataMap  数据对象
     * @return  是否成功
     * @author XuChao
     */
    public static boolean createFileAndWriterData(String directoryPath, String fileName, Map<String, String> dataMap) {
        boolean b = createFileHandle(directoryPath, fileName);
        if (!b) {
            throw new RuntimeException("文件创建失败");
        }
        return FileUtil.writerDataToFile(directoryPath + fileName, dataMap);
    }

    /**
     * 给目录文件，将传入的Map集合键值对的形式写入文件中
     * @param path  路径   D:\\a\\b.txt
     * @param dataMap 数据对象
     * @return 是否写入成功
     * @author XuChao
     */
    public static boolean writerDataToFile(String path, Map<String, String> dataMap) {
        try(
             BufferedWriter br = new BufferedWriter(new FileWriter(path));
        ) {
            Set<Map.Entry<String, String>> entries = dataMap.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                br.write(entry.getKey() + "=" + entry.getValue());
                br.newLine();
            }
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 读取文件中的数据，返回指定对象
     * @param t  对象 例如：new Demo();
     * @param path  文件路径
     * @param queryFields  查询的字段与文件中的键和实体类的属性要保存一致
     * @param <T>  标识
     * @return  返回的传入对象
     * @author XuChao
     */
    public static <T> T readFileData(T t, String path, String ...queryFields) {
        try(FileReader reader = new FileReader(path)) {
            Properties prop = new Properties();
            // 加载FileReader
            prop.load(reader);
            // 获取字节码
            Class<?> clazz = t.getClass();
            for (String field : queryFields) {
                // 获取类字段并设置数据
                Field objFiled = clazz.getDeclaredField(field);
                objFiled.setAccessible(true);
                objFiled.set(t, prop.get(field));
            }
            return t;
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("读取文件失败 {}", e.getMessage(), e);
            return null;
        }

    }

    /**
     * 读取文件数据，返回Map集合
     * @param path  文件路径
     * @param queryFields 查询的字段，要与文件里的键保存一致
     * @return Map集合
     */
    public static Map<String, String> readFileDataToMap(String path, String ...queryFields) {
        try(FileReader reader = new FileReader(path)) {
            Map<String, String> retMap = new HashMap<String, String>(8);
            Properties prop = new Properties();
            // 加载FileReader
            prop.load(reader);
            for (String field : queryFields) {
                retMap.put(field, prop.get(field).toString());
            }
           return retMap;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        }
    }

    /**
     * 给出路径和文件名，进行创建
     * @param directoryPath 路径
     * @param fileName 文件名
     * @return 是否创建成功
     * @author XuChao
     */
    private static boolean createFileHandle(String directoryPath, String fileName) {
        Path dirPath = Paths.get(directoryPath);
        if (Files.exists(dirPath) && Files.isDirectory(dirPath)) {
            Path filePath = dirPath.resolve(fileName);
            if (!Files.exists(filePath) && !Files.isRegularFile(filePath)) {
                try {
                    Files.createFile(filePath);
                    log.info("文件位置路径: {}", filePath.toString());
                } catch (IOException e) {
                    e.printStackTrace();
                    log.warn("文件创建失败 {}", e.getMessage(), e);
                    return false;
                }
            }
            log.info("文件位置路径: {}", filePath.toString());
        } else {
            try {
                Files.createDirectories(dirPath);
                Path filePath = dirPath.resolve(fileName);
                Files.createFile(filePath);
                log.info("文件位置路径: {}", filePath.toString());
            } catch (IOException e) {
                e.printStackTrace();
                log.warn("文件创建失败 {}", e.getMessage(), e);
                return false;
            }
        }
        return true;
    }

}
